#define xuser mixc::powerful_cat
#include"lang/cxx/format.hpp"
#include"lang/cxx.hpp"
#include"mixc.hpp"
#include"utils/counter.hpp"

xinit(xuser::the_main){
    using namespace xuser;
    counter demo = 0;

    enum { max_buffer = 128 };
    char buf[max_buffer];

    // 注意：
    // 每次返回的地址是一样的，所以是新值覆盖旧值的逻辑
    // 所以是新值覆盖旧值的逻辑
    auto alloc = [&](uxx length) -> char * {
        if (length >= max_buffer){
            return nullptr; // 返回 null 并不会导致异常，只是会终止分配后续的操作，如果没有特殊要求，则会生成空串
        }
        else{
            buf[length] = '\0'; // \0 终结符不是必须的，如果你想和 cstr 兼容，可以这么做
            return buf;
        }
    };

    // 演示：小写 16 进制占位符 'h'
    {
        xhint(demo, "placeholder 'h'");

        // content:"12ab"
        xhint(h{0x12ab}.format(alloc));

        // 指针类型也会被转换成数值
        // content:"abc1234"
        xhint(h{(voidp)0xabc1234}.format(alloc));
    }

    // 演示：大写 16 进制占位符 'H'
    {
        xhint(demo, "placeholder 'H'");

        // content:"12AB"
        xhint(H{0x12ab}.format(alloc));

        // 指针类型也会被转换成数值
        // content:"ABC1234"
        xhint(H{(voidp)0xabc1234}.format(alloc));
    }

    // 演示：保留前导零的小写 16 进制占位符 'zh'
    {
        xhint(demo, "placeholder 'zh'");

        // 由于 i32 具有 8 位 16 进制，实际的值只占用 4 位，所以会有 4 个前导零
        // 前导零的个数与数值类型的位数有关
        // content:"000012ab"
        xhint(zh{0x12ab}.format(alloc));

        // 指针类型也会被转换成数值
        // 对于 32bit 系统：
        // content:"0abc1234"
        // 对于 64bit 系统：
        // content:"000000000abc1234"
        xhint(zh{(voidp)0xabc1234}.format(alloc));
    }

    // 演示：保留前导零的大写 16 进制占位符 'zH'
    {
        xhint(demo, "placeholder 'zH'");

        // 由于 i32 具有 8 位 16 进制，value 实际的值只占用 4 位，所以会有 4 个前导零
        // 前导零的个数与数值类型的位数有关
        // content:"000012AB"
        xhint(zH{0x12ab}.format(alloc));

        // 指针类型也会被转换成数值
        // 对于 32bit 系统（指针是 32bit）：
        // content:"0ABC1234"
        // 对于 64bit 系统（指针是 64bit）：
        // content:"000000000ABC1234"
        xhint(zH{(voidp)0xabc1234}.format(alloc));
    }

    // 演示：带 "0x" 前缀的小写 16 进制占位符 'x'
    {
        xhint(demo, "placeholder 'x'");

        // content:"0x12ab"
        xhint(x{0x12ab}.format(alloc));

        // 指针类型也会被转换成数值
        // content:"0xabc1234"
        xhint(x{(voidp)0xabc1234}.format(alloc));
    }

    // 演示：带 "0x" 前缀的大写 16 进制占位符 'X'
    {
        xhint(demo, "placeholder 'X'");

        // content:"0x12AB"
        xhint(X{0x12ab}.format(alloc));

        // 指针类型也会被转换成数值
        // content:"0xABC1234"
        xhint(X{(voidp)0xabc1234}.format(alloc));
    }

    // 演示：带 "0x" 前缀和前导零的小写 16 进制占位符 'zx'
    {
        xhint(demo, "placeholder 'zx'");

        // 由于 i32 具有 8 位 16 进制，value 实际的值只占用 4 位，所以会有 4 个前导零
        // 前导零的个数与 value 数值类型的位数有关
        // content:"0x000012ab"
        xhint(zx{0x12ab}.format(alloc));

        // 指针类型也会被转换成数值
        // 对于 32bit 系统（指针是 32bit）：
        // content:"0x0abc1234"
        // 对于 64bit 系统（指针是 64bit）：
        // content:"0x000000000abc1234"
        xhint(zx{(voidp)0xabc1234}.format(alloc));
    }

    // 演示：带 "0x" 前缀和前导零的大写 16 进制占位符 'zX'
    {
        xhint(demo, "placeholder 'zX'");

        // 由于 i32 具有 8 位 16 进制，value 实际的值只占用 4 位，所以会有 4 个前导零
        // 前导零的个数与 value 数值类型的位数有关
        // content:"0x000012AB"
        xhint(zX{0x12ab}.format(alloc));

        // 指针类型也会被转换成数值
        // 对于 32bit 系统（指针是 32bit）：
        // content:"0x0ABC1234"
        // 对于 64bit 系统（指针是 64bit）：
        // content:"0x000000000ABC1234"
        xhint(zX{(voidp)0xabc1234}.format(alloc));
    }

    // 演示：通用占位符 'vl'
    {
        xhint(demo, "placeholder 'vl'");

        xhint(v{996}.format(alloc));

        // \v 为占位符标识
        // 那么后续元素的内容都会填充到 \v 对应的位置

        // 显示 "2021-1-1"
        xhint(vl{2021,1,1}.format("\v-\v-\v", alloc));

        // 'vl' 还支持占位符的嵌套
        xhint(vl{ h(123), v{123}.radix(8), v{123}.radix(2) }.format("0x\v=0\v=0b\v", alloc));
    }

    // 演示：左对齐
    {
        // ph 命名空间下的所有占位符都支持对齐
        xhint(demo, "align left 'placeholder::l()'");

        // 左对齐 10 个字符单位
        // 显示 "996       is horrible"
        xhint(vl{ v{996}.l(10), "is horrible" }.format(alloc));

        // 左对齐 10 个字符单位，空出的部分用 '?' 填充
        // 显示 "996???????is horrible"
        xhint(vl{ v{996}.l(10, '?'), "is horrible" }.format(alloc));
    }

    // 演示：右对齐
    {
        // ph 命名空间下的所有占位符都支持对齐
        xhint(demo, "align right 'placeholder::r()'");

        // 右对齐 10 个字符单位，空出的部分用 ' ' 填充
        // 显示 "the shit working mode       996"
        xhint(vl{ "the shit working mode", v{996}.r(10)  }.format(alloc));

        // 右对齐 10 个字符单位，空出的部分用 '?' 填充
        // 显示 "the shit working mode-------996"
        xhint(vl{ "the shit working mode", v{996}.r(10, '-')  }.format(alloc));
    }


    // 演示：右对齐二/八进制补上前导 0
    {
        // ph 命名空间下的所有占位符都支持对齐
        xhint(demo, "align right 'placeholder::r()'");

        // 右对齐 16 个字符单位，空出的部分用 '0' 填充
        // 显示 "oct:0000000000001744"
        xhint(vl{ "oct:", v{01744/* 0 开头的数字是 8 进制 */}.r(16, '0').radix(8) }.format(alloc));

        // 右对齐 16 个字符单位，空出的部分用 '0' 填充
        // 显示 "bin:0000001111100100"
        xhint(vl{ "bin:", v{0b1111100100}.r(16, '0').radix(2) }.format(alloc));
    }

    // 演示：居中
    {
        // ph 命名空间下的所有占位符都支持对齐
        xhint(demo, "align center 'placeholder::c()'");

        // 居中 16 个字符单位，空出的部分用 ' ' 填充
        // 显示 "      996       "
        xhint(v{996}.c(16).format(alloc));

        // 右对齐 16 个字符单位，空出的部分用 '?' 填充
        // 显示 "??????996???????"
        xhint(v{996}.c(16, '?').format(alloc));
    }
};
